AWS CLI v2をAnsibleでMacにインストールしてみた
こんにちは。サービスグループの武田です。
先日、待望のAWS CLI v2がGAになりましたね!
ちょうどMacのセットアップをAnsibleに任せようと思っていたところだったので、さっそくAnsibleのプレイブックを書いてみました。
環境
次の環境で検証しました。
$ sw_vers ProductName: Mac OS X ProductVersion: 10.15.3 BuildVersion: 19D76 $ ansible-playbook --version | grep -E 'playbook|version' ansible-playbook 2.9.3 executable location = /usr/local/bin/ansible-playbook python version = 3.8.1 (default, Dec 27 2019, 18:06:00) [Clang 11.0.0 (clang-1100.0.33.16)]
またディレクトリの構成は次のようになっています。
$ tree . ├── ansible.cfg ├── hosts ├── roles │ └── awscli │ └── tasks │ └── main.yml └── site.yml 3 directories, 4 files
周辺ファイル
先に本質ではない部分のファイルをざっと紹介します。
ansible.cfgは全体の設定をするファイルです。今回はinterpreter_python
のみ指定しています。
[defaults] interpreter_python=/usr/bin/python3
インベントリファイルです。名前は任意ですが、今回はhosts
としました。
[localhost] 127.0.0.1
プレイブックの本体です。これも名前は任意ですが、今回はsite.yml
としました。AWS CLIをインストールする設定はロールとして切り出したため、roles
で指定しています。
--- - name: ansible hosts: localhost connection: local become: no gather_facts: no roles: - awscli
AWS CLIをインストールするプレイブック
それではawscliロールのプレイブックを紹介します。name: check awscli
とwhen: result.rc == 1
はセットで、AWS CLIがインストールされているかの事前チェックをしています。このチェックを挟まない場合、プレイブックを実行するたびにダウンロードおよびインストール処理をします。name: download awscli installer
はインストーラのダウンロードをしています。validate_certs: no
を指定しないと失敗してしまったのですが、根本的な解決策をご存じの方は教えてください。name: install awscli
が実際にインストールをする箇所です。実行にはsudo
が必要なため、become: yes
を指定しています。最後のname: add completion to .bashrc
はコマンド補完を有効にするための設定を.bashrc
に追記しています。zshなどを使用している場合はそれ用に書き換えてください。
--- - block: - name: check awscli command: "which aws" register: result check_mode: no changed_when: no failed_when: no - block: - name: download awscli installer get_url: url: https://awscli.amazonaws.com/AWSCLIV2.pkg dest: /tmp/AWSCLIV2.pkg validate_certs: no register: download - name: install awscli become: yes command: "installer -pkg {{ download.dest }} -target /" when: result.rc == 1 - name: add completion to .bashrc lineinfile: path: ~/.bashrc line: complete -C aws_completer aws tags: - awscli
それでは書いたプレイブックを実行してみます!
$ ansible-playbook -i hosts site.yml PLAY [ansible] ************************************************************************************* TASK [awscli : check awscli] *********************************************************************** ok: [127.0.0.1] TASK [awscli : download awscli installer] ********************************************************** changed: [127.0.0.1] TASK [awscli : install awscli] ********************************************************************* fatal: [127.0.0.1]: FAILED! => {"changed": false, "module_stderr": "sudo: a password is required\n", "module_stdout": "", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 1} PLAY RECAP ***************************************************************************************** 127.0.0.1 : ok=2 changed=1 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
おや、sudo
が必要な箇所で失敗してますね。というわけで後半戦はこのエラーを解決します。
sudoを実行する3つの方法
おそらく普段からAnsibleを使っている方は慣れたものでしょうが、何らかの方法でsudo
を実行するためのパスワードを指定する必要があります。一応sudoersにパスワードなしで実行できるように設定する方法もありますが、今回は除外します。ざっと調べた限り3つの方法がありましたので、それぞれ紹介します。
-K
オプションを指定し、実行時にパスワードを入力する
3つの方法の中で、これが一番簡単です。実行時に-K
オプションを指定するだけです。この方法のメリットは、2回目以降はwhen: result.rc == 1
がfalse
になるはずですので、オプションを指定しなくてもよくなることです(sudo
が必要な処理がスキップされるため)。その結果、パスワードの入力が必要なのは初回だけということになります。
$ ansible-playbook -i hosts site.yml -K
環境変数としてパスワードを指定する
sudo
のパスワードは、環境変数ansible_become_password
が定義されているとこれを使ってくれます(他にもエイリアスあり)。
sudo – Substitute User DO — Ansible Documentation
環境変数は実行時に引数として指定することもできますし、インベントリファイルなどに定義することも可能です。
たとえば実行時に指定するなら次のようになります。
$ ansible-playbook -i hosts site.yml -e 'ansible_become_password=hogehoge'
ただコマンドヒストリなどに残ってしまうのはちょっと嫌ですね。またインベントリファイルで指定するなら次のようになります。
[localhost] 127.0.0.1 ansible_become_password=hogehoge
ただしファイルに書いてしまうとバージョン管理にコミットできない(少なくともコミットしたくない)ため、管理上問題になりそうです。
というわけで、2番目の方法はインタラクティブにパスワードを入力する必要はなくなりますが、ちょっと嫌味が残ってしまうなというのが感想です。
Vaultでパスワードを管理する
最後に紹介するのは、Ansibleが提供しているファイルの暗号化機能を利用したものです。ansible-vault
コマンドを使用して簡単に用意できます。
まずは全体で共通の環境変数を定義するためgroup_vars/all.yml
を作成します。作成時にVaultパスワードの入力が求められるため適当に入力します。
$ ansible-vault create group_vars/all.yml New Vault password: Confirm New Vault password:
エディタが開かれたら、次のようにパスワードを定義します。
--- ansible_become_password: hogehoge
これで暗号化されたファイルが用意できました。あとは実行時に--ask-vault-pass
オプションを指定して実行するだけです。
$ ansible-playbook -i hosts site.yml --ask-vault-pass
この方法のメリットは平文でパスワードを管理しなくてよくなることです。ただし今回のケースにおいてはデメリットの方が大きいと感じました。まずプレイブック実行時に、毎回--ask-vault-pass
オプションを指定する必要があること *1。毎回パスワードを入力しなければいけないこと *2。そもそも、どうせ入力するなら初めからMacのパスワードを入力すれば済むこと。
たくさんのサーバーにプロビジョニングする場合などは別ですが、今回のようにあくまでローカルマシンで実行するだけなら、Vaultはやりすぎかなと。というわけで、私は1番目の方法を採用しています。
まとめ
Ansibleを使ったAWS CLI v2のインストール方法(プレイブック)と、sudo
実行について紹介しました。Ansibleのプレイブックを書くのは本当に数年ぶりで、調べることが多くてたいへんです。が、とても便利ですね!